//
//  COCallViewController.swift
//  CocoProject
//
//  Created by Vill on 2023/11/10.
//

import UIKit
import Alamofire
import StoreKit
import IQKeyboardManagerSwift
import ZegoExpressEngine
import SwiftyJSON

class COCallViewController: COBaseController {
    
    var anchorModel = DGChatUserInfoModel()   // 主播个人信息
    var isCalling:Bool! = false         // 是否主动拨打
    private var hangUpAuto: Timer!     // 自动挂断（用于接听电话时展示）
    private var isConnectedZego :Bool = false  // 是否已连接即构
    private var dialTimer: COCallTimeTool!
    private var dailCount: Int = 0       // 计时
    private var badQualityCount: Int = 0    // 网络质量差计时
    private var serverId: String! = ""
    
    // 禁止息屏
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        UIApplication.shared.isIdleTimerDisabled = false
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        UIApplication.shared.isIdleTimerDisabled = true
    }
    
    // 拨打界面
    lazy var callStatusView: COCallStatusView = {
        let call = COCallStatusView()
        call.callBolck = { [weak self] type in
            // type 1:拒绝来电 2:接听来电 3:挂断拨打电话
            if type == 1{
                self?.hangUpAction()
            }else if type == 2{
                self?.answerAction()
            }else if type == 3{
                self?.hangUpAction()
            }
        }
        return call
    }()
    
    // 底部按钮
    lazy var bottomView: COCallBottomView = {
        let call = COCallBottomView()
        call.callBolck = { [weak self] (type,sender) in
            if type == 1{
                self?.keyboardView.isHidden = false
                self?.keyboardView.chatTextView.becomeFirstResponder()
            }else if type == 2{
                sender!.isSelected = !sender!.isSelected
                ZegoExpressEngine.shared().muteMicrophone(sender!.isSelected)
            }else if type == 3{
                self?.sendGiftMessage(block: { model in
                    self?.giftMsgWithModel(model: model)
                })
            }
        }
        return call
    }()
    
    // 顶部View
    lazy var topView: COCallTopView = {
        let top = COCallTopView(frame: CGRect(x: 0, y: 0, width: SCREENWIDTH, height: PTW(130) + statusBarHeight))
        top.callBack = {[weak self] type in
            let closeAlert = COVideoCloseView(frame: CGRect(x: 0, y: 0, width: SCREENWIDTH, height: SCREENHEIGHT))
            closeAlert.showInView(view: nil)
            closeAlert.endCallBlock = { [weak self] in
                DispatchQueue.main.async {
                    // 关闭
                    self?.hangUpAction()
                }
            }
        }
        return top
    }()
    
    // 头像
    lazy var iconImg: UIImageView = {
        let icon = UIImageView()
        icon.contentMode = .scaleAspectFill
        icon.clipsToBounds = true
        icon.backgroundColor = UIColor.blue
        return icon
    }()
    
    // 主播图像
    lazy var anchorCanvas: UIView = {
        let view = UIView()
        return view
    }()
    
    // 自己画面
    lazy var myCanvas: COCanvasLocalView = {
        let can = COCanvasLocalView(frame: CGRect(x: SCREENWIDTH - PTW(115), y: statusBarHeight + PTW(10), width: PTW(100), height: PTW(150)))
        can.flipBtn.isSelected = true
        can.addTap { [weak self] ges in
            guard let `self` = self else { return }
            can.flipBtn.isSelected = !can.flipBtn.isSelected
            ZegoExpressEngine.shared().useFrontCamera(can.flipBtn.isSelected)
        }
        return can
    }()
    
    // 礼物发送显示横幅
    lazy var showGiftView: COCallGiftView = {
        let view = COCallGiftView(frame: CGRect(x: 0, y: PTW(130) + statusBarHeight, width:PTW(300), height: PTW(200)))
        return view
    }()
    
    // 文本输入框
    private lazy var keyboardView: ChatKeyboardView = {
        let view = ChatKeyboardView(frame: CGRect(x: 0, y: SCREENHEIGHT, width: SCREENWIDTH, height: 52))
        view.delegate = self
        return view
    }()
    
    //MARK: --------- 聊天容器 ---------
    lazy var chatContain : UIView = {
        let chat = UIView()
        return chat
    }()
    
    //MARK: --------- 聊天窗口 ------------
    lazy var containerView:COCallSessionController = {
        let contain = COCallSessionController()
        return contain
    }()
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        IQKeyboardManager.shared.enable = false
        KAppDelegate.changeMyStatusOnline(1)  // 更改我的在线状态
        NotificationCenter.default.post(name: .NewUserRechargeNotification, object: nil, userInfo: ["type":1])
        NotificationCenter.default.post(name: .RandomTimeRunNotification, object: nil, userInfo: ["type":1])
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        IQKeyboardManager.shared.enable = true
        COAudioPlayer.shared.stop()
        kLiveCalling.keySaveToNSDefaults(with: false)
        KAppDelegate.changeMyStatusOnline(0)  // 更改我的在线状态
        let config = URLSessionConfiguration.default
        Alamofire.Session(configuration: config).cancelAllRequests()
        NotificationCenter.default.post(name: .NewUserRechargeNotification, object: nil, userInfo: ["type":0])
        NotificationCenter.default.post(name: .RandomTimeRunNotification, object: nil, userInfo: ["type":0])
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if (self.dailCount > 120 && feed == false){
            if #available(iOS 10.3, *) {
                SKStoreReviewController.requestReview()
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        ZegoExpressEngine.shared().stopPreview()
        ZegoExpressEngine.shared().stopPublishingStream()
        ZegoExpressEngine.destroy(nil)
        
        self.xl_interactivePopDisabled = false
        self.edgesForExtendedLayout = .all
        COChatMsgManager.shared.callViewController = self
        kLiveCalling.keySaveToNSDefaults(with: true)
        self.audioPlayer()   // 播放语音
        if isCalling{
            // 主动拨打创建即构
            creatZegoEngine()
        }
        // 自动挂断
        hangUpAuto = Timer.scheduledTimer(timeInterval: 25, target: self, selector: #selector(hangUpAutoAction), userInfo: nil, repeats: false)
        RunLoop.main.add(hangUpAuto, forMode: .common)
        
        // 收到融云消息
        COChatMsgManager.shared.rcGetMessageCallback = { [weak self] (message, lefts) in
            guard let `self` = self else { return }
            self.rongcloudReceived(message: message, left: lefts)
        }
        addSubViewsUI()
        // 设置用户信息
        setInfoData()
    }

    func addSubViewsUI(){
        view.addSubview(iconImg)
        view.addSubview(anchorCanvas)
        view.addSubview(bottomView)
        view.addSubview(topView)
        view.addSubview(showGiftView)        // 礼物显示栏
        view.addSubview(myCanvas)
        
        containerView.view.backgroundColor = UIColor.clear
        chatContain = containerView.view
        chatContain.frame = CGRect(x: PTW(15), y: SCREENHEIGHT - PTW(250) , width: PTW(300), height: PTW(180) - KSafeBottomMargin)
        view.addSubview(chatContain)
        
        iconImg.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        anchorCanvas.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        bottomView.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(PTW(60))
            make.bottom.equalToSuperview().offset(-KSafeBottomMargin - PTW(5))
        }
        view.addSubview(callStatusView)
        callStatusView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        view.addSubview(keyboardView)        // 文本输入框
        keyboardView.isHidden = true
    }
    
    //MARK: ----------- 设置用户数据 ------------
    func setInfoData(){
        self.iconImg.sd_setUrlImage(anchorModel.profilePhoto, placeholder: KImaged("coco_icon_holder"))
        self.topView.nameLbl.text = anchorModel.name
        self.callStatusView.setUserInfo(model: anchorModel, iscalling: isCalling)
    }
    
    deinit{
        COChatMsgManager.shared.callViewController = nil
        self.deinitAutoHangUp()          // 销毁当前倒计时
        self.deinitDialTimer()           // 移除倒计时
    }
}

extension COCallViewController:ZegoEventHandler{
    
    // 创建即构
    func creatZegoEngine(){
        var params = [String:Any]()
        params["roomId"]  = anchorModel.id
        COHttpManager.request(target: COBaseApi.consumeZegoToken(param: params), modelType: COCallResponseModel.self) { code, object, success in
            if (success == true){
                ZegoExpressEngine.createEngine(withAppID: UInt32((object?.response.AppId)!)!, appSign: (object?.response.AppSign)!, isTestEnv: KZegoTestEnv, scenario: .general, eventHandler: self)
                self.loginZegoRoom(with: (object?.response.token)!)
            }else{
                // 挂断电话
                self.hangUpAction()
            }
        } failureBlock: { code, msg in
            // 挂断电话
            self.hangUpAction()
        }
    }
    
    //MARK: -------------- 登陆房间 ----------------
    func loginZegoRoom(with token:String){
        // 登陆房间
        let user = COUserInfoManager.shared.curUser
        let zegoUser = ZegoUser(userID: "customer-\(user?.userResponse.id ?? "")", userName: user?.userResponse.nickName ?? "null")
        let config = ZegoRoomConfig()
        config.token = token
        config.isUserStatusNotify = true
        ZegoExpressEngine.shared().loginRoom((self.anchorModel.id), user: zegoUser, config: config)
        self.isConnectedZego = true;
        // 登陆房间，开始推流
        zegoPublishingStream()
    }
    
    //MARK: --------------- 开始推流 -------------------
    func zegoPublishingStream(){
        let user = COUserInfoManager.shared.curUser
        ZegoExpressEngine.shared().startPublishingStream("customer-\(user?.userResponse.id ?? "")")
        let canvas = ZegoCanvas(view: self.myCanvas.canvas)
        canvas.viewMode = .aspectFill
        ZegoExpressEngine.shared().startPreview(canvas)
        print(" --- 开始推流 ---- ")
    }
    
    //MARK: --------------- 开始拉流 -------------------
    func zegoPlayingStream(streamId: String){
        startDialTimerRun()    // 开启倒计时
        if (COUserInfoManager.giftsLoaded() == false){
            KAppDelegate.getGiftSearchList()
            return
        }
        let canvas = ZegoCanvas(view: anchorCanvas)
        canvas.viewMode = .aspectFill
        ZegoExpressEngine.shared().startPlayingStream(streamId, canvas: canvas)
        print(" --- 开始拉流 ---- ")
    }
    
    //MARK: ---------- 开启计时器 -----------
    func startDialTimerRun(){
        dialTimer = COCallTimeTool.scheduledTimer(timeInterval: 1, target: self, selector: #selector(dialTimerRun), userInfo: nil, repeats: true)
        dialTimer.fire()
    }
    
    //MARK: ---------- 开始计时 -----------
    // 移除计时器
    func deinitDialTimer(){
        guard let _ = dialTimer else {
            return
        }
        dialTimer.invalidate()
        dialTimer = nil
    }
    
    // 计时器开始
    @objc func dialTimerRun(){
        let hours = Int(dailCount / 3600)
        let minutes = Int((dailCount % 3600) / 60)
        let seconds = Int(dailCount % 60)
        DispatchQueue.main.safeAsync {
            self.topView.timeLbl.text = String(format: " %02d:%02d:%02d", hours, minutes, seconds)
            if (self.dailCount) % 60 == 0 {
                self.deductionWithCoin()
            }
            self.dailCount += 1
        }
    }

    //MARK: ---------- 扣币 -----------
    func deductionWithCoin(){
        let time = Date().timeIntervalSince1970 * 1000
        var params = [String:Any]()
        params["callTime"]   =  "60"
        params["streamerId"] = anchorModel.id
        params["time"] =  String(format: "%.f", time)
        if self.serverId.isEmptyStr == false{
            params["id"] = self.serverId
        }
        COHttpManager.request(target: COBaseApi.getNewZegoToken(param: params), modelType: COConsumeCallModel.self) { code, object, success in
            if (success == true){
                self.serverId = String(object?.recordId ?? 0)
                var user = COUserInfoManager.shared.curUser
                user?.userResponse.balance -= self.anchorModel.price
                COUserInfoManager.shared.curUser = user
                COUserInfoManager.coSaveInfo()
                AppPurchaseManager.updateBalance()
                self.checkUserBalance()
            }else{
                //200处理成功，其他参数都需要手机挂断通话50036（金币不足），50035系统错误
                if code == 50036{
                    self.hangUpAction()
                    self.checkUserBalance()
                }else if code == 50035{
                    UIToolHelper.makeToast("Network anomaly")
                    self.hangUpAction()
                }else{
                    UIToolHelper.makeToast("Network error")
                    self.hangUpAction()
                }
            }
        } failureBlock: { code, msg in
            self.hangUpAction()
        }
    }

    // 检查自己的余额
    private func checkUserBalance(_ ischeck:Bool = false) {
        let user = COUserInfoManager.shared.curUser
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if user?.userResponse.balance ?? 0 < anchorModel.price && feed == false{
            //金币不足
            let balanceAlert = COBalanceAlertView.init(coins: user?.userResponse.balance ?? 0, subtitle: "You don't have enough balance\nfor one minute")
            balanceAlert.show()
            balanceAlert.certainBlock = {
                DispatchQueue.main.async {
                    self.goRechargeWithGift()
                }
            }
            return
        }
    }
    
    //MARK: ------------------  挂断 -----------------------
    func hangUpAction(){
        // 移除网络请求
        let config = URLSessionConfiguration.default
        Alamofire.Session(configuration: config).cancelAllRequests()
        COAudioPlayer.shared.stop()   // 停止铃声
        self.deinitAutoHangUp()          // 销毁当前倒计时
        self.deinitDialTimer()           // 移除倒计时
        let user = COUserInfoManager.shared.curUser
        let params = [
            "streamerId": self.anchorModel.id,
            "customerId": user?.userResponse.id
        ]
        let json = JSON(params)
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        let rongcloudId = feed == true ? "client_\(anchorModel.id)" : "streamer_\(anchorModel.id)"
        if let jsonString = json.rawString() {
            let message = RCCommandMessage(name: "hangup", data: jsonString)
            RCIMClient.shared().sendMessage(.ConversationType_PRIVATE, targetId: rongcloudId, content: message, pushContent: nil, pushData: nil) { (messageId) in
                print("hangup success")
                print("========================== 挂断电话消息发送了 =========================")
            } error: { (errorCode, messageId) in
                print("hangup fail")
            }
        }
        self.cancelAnimation()
    }
    
    //MARK: ------------------------- 返回 ------------------------
    func cancelAnimation(){
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if self.isConnectedZego{
            print(" ----  退出即构房间 停止推拉流 --- ")
            let targetId = feed == true ? "customer-\(anchorModel.id)": "streamer-\(anchorModel.id)"
            ZegoExpressEngine.shared().stopPlayingStream(targetId)
            ZegoExpressEngine.shared().logoutRoom(self.anchorModel.id)
        }
        ZegoExpressEngine.shared().stopPreview()
        ZegoExpressEngine.shared().stopPublishingStream()
        ZegoExpressEngine.destroy(nil)
        print(" ----  销毁了引擎 --- ")

        KAppDelegate.changeMyStatusOnline(0)  // 更改我的在线状态
        UIApplication.shared.isIdleTimerDisabled = false
        kLiveCalling.keySaveToNSDefaults(with: false)
        COAudioPlayer.shared.stop()
        IQKeyboardManager.shared.enable = true // 键盘处理
        self.deinitDialTimer()           // 移除倒计时12
        // 消除消息未读数量
        let rongcloudId = feed == true ? "client_\(anchorModel.id)" : "streamer_\(anchorModel.id)"
        RCIMClient.shared().clearMessagesUnreadStatus(.ConversationType_PRIVATE, targetId: rongcloudId)
        COChatMsgManager.shared.setBadgeValue()
        if (self.dailCount > 0 && feed == false){
            // 只要通过话就可以绑定邮箱
            let readyCalled = kIsAllreadyCalled.keyGetNSDefaultsKey() as? Bool
            if (readyCalled == false){
                kIsAllreadyCalled.keySaveToNSDefaults(with: true)
            }
            let firstCalled = kIsFirstCalledBind.keyGetNSDefaultsKey() as? Bool
            if (firstCalled == false){
                NotificationCenter.default.post(name: .kIsNeedBindEmail, object: nil)
                kIsFirstCalledBind.keySaveToNSDefaults(with: true)
            }
        }
        
        if (self.dailCount > 0){
            // 新建将要push的控制器
            let comment = COCallPraiseController()
            comment.anchorModel = self.anchorModel
            comment.callId = self.serverId
            comment.callTime = String(self.dailCount)
            comment.hidesBottomBarWhenPushed = true
            if (self.navigationController == nil) {
                return
            }
            let vcarray = NSMutableArray(array: self.navigationController!.viewControllers)
            let index = vcarray.index(of: self)
            vcarray.removeObject(at: index)
            vcarray.add(comment)
            self.navigationController?.setViewControllers(vcarray as! [UIViewController], animated: true)
        }else{
            self.navigationController?.popViewController(animated: true)
        }
    }
    
    //MARK: ------------------  接听 -----------------------
    func answerAction(){
        if self.isConnectedZego && self.isCalling == false {return}
        print("----- 接听电话 ---")
        COAudioPlayer.shared.stop()     // 停止音乐
        self.deinitAutoHangUp()            // 释放自动拨打
        // 判断权限
        let audioStatus = AVCaptureDevice.authorizationStatus(for: .audio)
        let videoStatus = AVCaptureDevice.authorizationStatus(for: .video)
        if audioStatus == .notDetermined || videoStatus == .notDetermined {
            self.requestAVAuthorization()
            return
        }
        // 权限未开启，提示开启权限
        if !judgeAuthorPermisstion(){
            self.showAlert(style: .alert, title: nil, message: "You are not authorized to access the camera or microphone", actions: ["Click to authorize"]) { type in
                if let url = URL(string:UIApplication.openSettingsURLString) {
                      if #available(iOS 10.0, *) {
                            UIApplication.shared.open(url, options: [:], completionHandler: nil)
                      } else {
                            UIApplication.shared.openURL(url)
                      }
                }
            }
            return
        }
        let user = COUserInfoManager.shared.curUser
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if user?.userResponse.balance ?? 0 < anchorModel.price && feed == false{
            //金币不足
            let balanceAlert = COBalanceAlertView.init(coins: user?.userResponse.balance ?? 0, subtitle: "You don't have enough balance\nfor one minute")
            balanceAlert.show()
            balanceAlert.certainBlock = {
                DispatchQueue.main.async {
                    UIToolHelper.currentViewController()?.navigationController?.pushViewController(COBalanceController(), animated: true)
                }
            }
            self.hangUpAction()
            return
        }
        self.callStatusView.removeFromSuperview()       // 移除接听界面
        if !self.isCalling{
            creatZegoEngine()
        }
    }
    
    //房间状态更新回调，登陆房间后，当房间连接状态发生变更（如出现房间断开，登陆认证失败等情况），SDK会通过该回调通知
    func onRoomStateUpdate(_ state: ZegoRoomState, errorCode: Int32, extendedData: [AnyHashable : Any]?, roomID: String) {
        print("即构房间状态更新\(state)----\(errorCode)----\(roomID)")
    }
    
    // 用户状态更新，登陆房间后，当房间内有用户新增或删除时，SDK会通过该回调通知
    func onRoomUserUpdate(_ updateType: ZegoUpdateType, userList: [ZegoUser], roomID: String) {
        print("onRoomUserUpdate ------- ")
        if updateType == .delete {
            print("有用户离开房间\(userList)")
            guard !userList.isEmpty else { return }
            if let userId = userList.first {
                let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
                let currentStreamerId = feed == true ? "client-\(anchorModel.id)": "streamer-\(anchorModel.id)"
                if userId.userID.isEqual(currentStreamerId){
                    hangUpAction()   // 挂断电话
                }
            }
        }else {
            print("有用户加入房间\(userList)")
        }
    }
    
    // 流状态更新，登陆房间后，当房间内有用户新推送或删除音视频流时，SDK会通过该回调通知
    func onRoomStreamUpdate(_ updateType: ZegoUpdateType, streamList: [ZegoStream], extendedData: [AnyHashable : Any]?, roomID: String) {
        print("onRoomStreamUpdate ------- ")
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if updateType == .add {
            print("收到推流\(streamList)")
            guard !streamList.isEmpty else { return }
            if let stream = streamList.first {
                let currentStreamerId = feed == true ? "client-\(anchorModel.id)": "streamer-\(anchorModel.id)"
                if stream.streamID.isEqual(currentStreamerId){
                    answerAction()
                    zegoPlayingStream(streamId: stream.streamID)
                }
            }
        }else if updateType == .delete{
            print("流停止\(streamList)")
            guard !streamList.isEmpty else { return }
            if let stream = streamList.first {
                let currentStreamerId = feed == true ? "client-\(anchorModel.id)": "streamer-\(anchorModel.id)"
                if stream.streamID.isEqual(currentStreamerId){
                    hangUpAction() // 挂断电话
                }
            }
        }
    }
    
    func onPlayerQualityUpdate(_ quality: ZegoPlayStreamQuality, streamID: String) {
        if (quality.level == .bad || quality.level == .die || quality.videoRecvFPS == 0){
            self.badQualityCount += 1
            UIToolHelper.makeToast("Network is unstable")
            if self.badQualityCount == 5 {
                UIToolHelper.makeToast("Hang up automatically because of network problems")
                self.hangUpAction()
                self.giveDiamondIfNetwork()
            }
        }else{
            self.badQualityCount = 0
        }
    }
    
    // 返币
    func giveDiamondIfNetwork(){
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if feed == true || self.serverId.isEmptyStr == true {
            return
        }
        var params = [String:Any]()
        params["consumeId"] = self.serverId
        COHttpManager.request(target: COBaseApi.consumeDelay(param: params), modelType: CONSObjectModel.self) { code, object, success in
            AppPurchaseManager.updateBalance()
        } failureBlock: { code, msg in
        }
    }
}

//MARK: -------------- 即构相关 ----------------
extension COCallViewController:ChatKeyboardViewDelegate{
    //MARK: ------------------- 收到消息 --------------------------
    func rongcloudReceived(message: RCMessage, left: Int32){
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        if feed == false{
            let nowUser = "streamer_\(self.anchorModel.id)"
            if nowUser != message.senderUserId{
                return
            }
        }
        DispatchQueue.main.async { [weak self] in
            guard let `self` = self else { return }
            if message.conversationType == .ConversationType_SYSTEM{
                return
            }
            if message.content!.isMember(of: RCCommandMessage.self) {
                let command = message.content as! RCCommandMessage
                let json = JSON(parseJSON: command.data!)
                if json["streamerId"].stringValue == self.anchorModel.id {
                    self.hangUpAction()
                    return
                }
            }
            if message.content!.isMember(of: RCTextMessage.self) {
                self.translate(message: message)
            }else {
                self.showMessage(message: message)
            }
        }
    }
    
    private func showMessage(message: RCMessage) {
        let textMsg = message.content as! RCTextMessage
        self.containerView.log(type: .other, content: textMsg.content, nickName: textMsg.senderUserInfo!.name)
    }
    
    private func translate(message: RCMessage) {
        let textMessage = message.content as! RCTextMessage
        var params:[String:Any] = [:]
        params["q"] = textMessage.content
        var languageCode = "en"
        if let currentLanguage = Locale.preferredLanguages.first {
            if let range = currentLanguage.range(of: "-") {
                languageCode = String(currentLanguage[currentLanguage.startIndex..<range.lowerBound])
            }
        }
        params["target"] = languageCode
        COHttpManager.request(target: COBaseApi.translate(param: params), modelType: COTranslateResponseModel.self) {[weak self] code, object, success in
            UIToolHelper.hideHUD()
            if success == true{
                if object?.response.code == 200 {
                    let translatedText = object?.response.translatedText
                    textMessage.content = translatedText ?? ""
                }
            }
            let temp = message
            temp.content = textMessage
            self?.showMessage(message: temp)
        } failureBlock: {[weak self] code, msg in
            UIToolHelper.hideHUD()
            self?.showMessage(message: message)
        }
    }
    
    //MARK: --------------- 礼物消息 --------------
    func giftMsgWithModel(model:COGiftModel){
        var params = [String:Any]()
        params["id"]  = model.id
        params["streamerId"]  = anchorModel.id
        params["count"]  = 1
        params["giftType"]  = 1
        COHttpManager.request(target: COBaseApi.consumeGift(param: params), modelType: COConsumeGiftResponseModel.self) {[weak self] code, object, success in
            if(success == true){
                var curModel = COUserInfoManager.shared.curUser
                curModel?.userResponse.balance = object?.response.coins ?? 0
                COUserInfoManager.shared.curUser = curModel
                COUserInfoManager.coSaveInfo()
                self?.vertifyGiftWith(model: model)
            }else{
                if code == 60667 || code == 60666{
                    UIToolHelper.makeToast("You don't have enough balance,please recharge")
                    DispatchQueue.main.safeAsync {
                        self?.goRechargeWithGift()
                    }
                }else{
                    UIToolHelper.makeToast("Failed to send")
                }
            }
        } failureBlock: { code, msg in
            UIToolHelper.makeToast("Failed to send")
        }
    }
    
    //MARK: ------------- 赠送礼物扣币成功发送消息 ----------------
    func vertifyGiftWith(model: COGiftModel){
        AppPurchaseManager.updateBalance()
        let curuserModel = COUserInfoManager.shared.curUser
        let giftMsg = COGiftContent()
        giftMsg.id = model.id
        giftMsg.name = model.name
        giftMsg.cover = model.iconUrl
        giftMsg.fileUrl = model.fileUrl
        giftMsg.count = 1
        giftMsg.toStreamerName = anchorModel.name
        let userInfo = RCUserInfo(userId: curuserModel!.rcUserId, name: curuserModel?.userResponse.nickName, portrait:curuserModel?.userResponse.profilePhoto)
        giftMsg.senderUserInfo = userInfo
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        let targetId = feed == true ? "client_\(anchorModel.id)" : "streamer_\(anchorModel.id)"
        RCIMClient.shared().sendMessage(.ConversationType_PRIVATE, targetId: targetId, content: giftMsg, pushContent: "Receive a gift", pushData: nil) { (messageId) in
            DispatchQueue.main.async {
                self.showGiftView.show(gift: giftMsg)
                let text = "\(giftMsg.conversationDigest()!)"
                self.containerView.log(type: .mine, content: text, nickName: curuserModel?.userResponse.nickName ?? "x")
                self.playSvga(with: model.fileUrl)
            }
        } error: { (errorCode, messageId) in
            UIToolHelper.makeToast("Failed to send")
        }
    }

    private func playSvga(with url: String?) {
        guard url != nil else { return }
        SVGAPlayerUtil.shared.playView = self.view
        SVGAPlayerUtil.shared.fileUrl = url!
    }
    
    // 输入完消息
    func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String) {
        let curuserModel = COUserInfoManager.shared.curUser
        let messageContent = RCTextMessage(content: content)
        messageContent.senderUserInfo = RCUserInfo(userId: curuserModel!.rcUserId, name: curuserModel?.userResponse.nickName, portrait:curuserModel?.userResponse.profilePhoto)
        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
        let rongcloudId = feed == true ? "client_\(anchorModel.id)" : "streamer_\(anchorModel.id)"
        RCIMClient.shared().sendMessage(.ConversationType_PRIVATE, targetId:rongcloudId, content: messageContent, pushContent: "You received a new message", pushData: "You received a new message") { messageId in
            DispatchQueue.main.async {[weak self] in
                guard let `self` = self else { return }
                self.containerView.log(type: .mine, content: content, nickName: curuserModel?.userResponse.nickName ?? "x")
            }
        } error: { error, messageId in
            UIToolHelper.makeToast("Failed to send")
        }
    }
}

extension COCallViewController{
    //MARK: -------------- 播放呼叫语音 ----------------
    func audioPlayer(){
        // 播放音效
        DispatchQueue.main.asyncAfter(deadline: .now()+1, execute:{
            let path = Bundle.main.path(forResource: "callAudio", ofType: "mp3")!
            COAudioPlayer.shared.numberOfLoops = -1
            COAudioPlayer.shared.preparePlay(url: URL(fileURLWithPath: path))
            COAudioPlayer.shared.play()
            //播放代码
            do {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
                try AVAudioSession.sharedInstance().setActive(true)
            } catch {
            }
        })
    }
    
    // 自动挂断
    @objc func hangUpAutoAction(){
        // 销毁当前倒计时
        self.deinitAutoHangUp()
        // 挂断
        self.cancelAnimation()
    }
    
    // 移除自动挂断时间倒计时
    func deinitAutoHangUp(){
        guard let _ = hangUpAuto else {
            return
        }
        hangUpAuto.invalidate()
        hangUpAuto = nil
    }
    
}
